package com.thinkgsp.webapp.controller.sale;

import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import org.apache.commons.lang.StringUtils;
import org.jfree.util.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.thinkgsp.jxc.model.Bill;
import com.thinkgsp.jxc.model.BillAmount;
import com.thinkgsp.jxc.model.BillDetail;
import com.thinkgsp.jxc.model.Emp;
import com.thinkgsp.jxc.model.Inventory;
import com.thinkgsp.jxc.model.Product;
import com.thinkgsp.jxc.model.ProductBusProperties;
import com.thinkgsp.jxc.model.SalesStockOutBill;
import com.thinkgsp.jxc.service.BillService;
import com.thinkgsp.jxc.service.CustomerService;
import com.thinkgsp.jxc.service.InventoryService;
import com.thinkgsp.jxc.service.ProductService;
import com.thinkgsp.jxc.service.ServiceException;
import com.thinkgsp.report.JRBillDataSource;
import com.thinkgsp.sys.model.SysAccountPeriod;
import com.thinkgsp.sys.model.SysRole;
import com.thinkgsp.sys.model.SysUser;
import com.thinkgsp.sys.service.NumberRoleService;
import com.thinkgsp.webapp.controller.BaseController;
import com.thinkgsp.webapp.util.ExtReturn;
import com.thinkgsp.webapp.util.WebUtils;
@Controller
@RequestMapping(value = "/sale")
public class SaleBillController extends BaseController {
	@Autowired
	private BillService billService ;
	@Autowired
	private NumberRoleService numberRoleService;
	@Autowired
	private InventoryService inventoryService;
	@Autowired
	private ProductService product;
	
	@Autowired
	private CustomerService customerService;
	
	@RequestMapping("/query.do")
    @ResponseBody
    public Object  billQuery(@RequestParam java.sql.Date begDate,@RequestParam java.sql.Date endDate,@RequestParam Integer custId,@RequestParam Integer limit,@RequestParam Integer start){
		try {
			//return this.billService.findSalesStockOutBill(begDate, endDate, custId);
			return this.billService.findSalesStockOutBill(begDate, endDate, custId, start, limit);

		} catch (Exception e) {
			loger.debug(e.getMessage());
			return new ExtReturn(false,"查询销售单据信息出错",e);
			
		}
	}
	@RequestMapping("/queryNoPaging.do")
    @ResponseBody
    public Object  billQueryNoPaging(@RequestParam java.sql.Date begDate,@RequestParam java.sql.Date endDate,@RequestParam Integer custId){
		try {
			return this.billService.findSalesStockOutBill(begDate, endDate, custId);

		} catch (Exception e) {
			loger.debug(e.getMessage());
			return new ExtReturn(false,"查询销售单据信息出错",e);
			
		}
	}
	@RequestMapping(value="/createSaleBill.do",method=RequestMethod.GET)
	@ResponseBody
	public Object createSaleBill() {
		SalesStockOutBill bill=new SalesStockOutBill();
		SysAccountPeriod period = this.billService.getCurrentPeriod();
		bill.setFyear(period.getFyear());
		bill.setPeriod(period.getPeriod());
		Emp emp = billService.getCurrentEmp();
		bill.setEmp(emp);
		bill.setMaker(emp);
		bill.setDept(billService.getCurrentUser().getLogonDept());
		try {
			String billCode = numberRoleService.newNumber(2);
			bill.setBillCode(billCode);
		} catch(ServiceException e) {
			Log.error("New SaleBill codeNumber error:" + e.getMessage());
		}
		return bill;
	}

	
	@RequestMapping(value="/save.do" ,method = RequestMethod.POST )
	@ResponseBody
	public Object saveSaleBill(Model model ,@RequestBody SalesStockOutBill bill) {
		if(bill == null) {
			return new ExtReturn("单据无效。");
		}
		try {
			//有效性检查,库存及其它
			String rs=this.CheckProductInv(bill);
			if(!StringUtils.isEmpty(rs)){
				return new ExtReturn(false,"单据验证不通过,原因:<br/>"+rs);
			}
			
			SysUser user =null;
			user = (SysUser) SecurityContextHolder.getContext()
					    .getAuthentication()
					    .getPrincipal();
			boolean isPrivilege=false;
			for(SysRole role:user.getRoles()){
				if("ROLE_PRICE_PRIVILEGE".equals(role.getRoleName()))//当前用户是否有价格特权.
				{
					isPrivilege=true;
					break;
				}
			}
			
			if(!isPrivilege){//没有价格特权检查批发价
				String ps=this.CheckProductPirce(bill);
				if(!StringUtils.isEmpty(ps)){
					return new ExtReturn(false,"单据验证不通过,原因:<br/>"+ps);
				}
			}
			
			BillAmount amount=bill.recalcBillAmount();
			this.customerService.checkTradeCredit(bill.getCustId(),amount.getBillSettleAmount().intValue());
			this.billService.saveBill(bill);
			return new ExtReturn(true,"单据保存成功!",bill);
		} catch(Exception e) {
			return new ExtReturn("保存销售单据失败，原因:" + e.getMessage());
		}
	}
	private String CheckProductInv(Bill bill){
		StringBuilder sb=new StringBuilder();
		SysAccountPeriod ap= this.inventoryService.getCurrentPeriod();
		if(bill==null || bill.getDetails().size()<1) return null;
		int i=1;
		for (BillDetail detail: bill.getDetails()) {
			Inventory inv= this.inventoryService.findInventory(ap.getFyear(),ap.getPeriod(),detail.getProductId(),detail.getInvAddId(),detail.getBatchNoId());
			if(inv.getUsableQty().floatValue()<detail.getQuantity().floatValue()){
				sb.append("明细第 [");
				sb.append(i);
				sb.append("] 行 商品存货数量不足 可用数量:");
				sb.append(inv.getUsableQty());
				sb.append("<br/>");
			}
			i++;
		}
		if(sb.length()>0)
			return sb.toString();
		return null;
	}
	
	private String CheckProductPirce(Bill bill)
	{
		StringBuilder sb=new StringBuilder();
		if(bill==null || bill.getDetails().size()<1) return null;
		int i=1;
		for (BillDetail detail: bill.getDetails()) {
			Product prod= this.product.getProduct(detail.getProductId());
			ProductBusProperties pri= prod.getProductBusProperties();
			if(pri==null || pri.getSalePrice().floatValue()<=0) return null;
			if(detail.getPrice().floatValue()<pri.getSalePrice().floatValue()){
				sb.append("明细第 [");
				sb.append(i);
				sb.append("] 行 商品价格不能低于批发价:");
				sb.append(pri.getSalePrice());
				sb.append("<br/>");
			}
			i++;
		}
		if(sb.length()>0)
			return sb.toString();
		return null;
	}
	
	@RequestMapping(value="/getBill.do")
	@ResponseBody
	public Object getBill(@RequestParam Long billId) {
		try {
			return this.billService.getBill(billId);
		} catch(Exception e) {
			loger.debug(e.getMessage());
			return new ExtReturn("获取销售单出错:"+e.getMessage());
		}
	}
	
	@RequestMapping(value="/archive.do")
	@ResponseBody
	public Object archiveSaleBill(@RequestParam Long billId) {
		if(billId == null || billId == 0L) {
			return new ExtReturn("参数无效。");
		}
		try {
			this.billService.archiveBill(billId);
			return new ExtReturn(true,"单据归档成功!");
		} catch(Exception e) {
			loger.debug(e.getMessage());
			return new ExtReturn(false,"单据归档失败,原因:" + e.getMessage());
		}
	}
	
	@RequestMapping(value="/unArchive.do")
	@ResponseBody
	public Object unArchiveSaleBill(@RequestParam Long billId) {
		if(billId == null || billId == 0L) {
			return new ExtReturn("参数无效。");
		}
		try {
			this.billService.unArchiveBill(billId);
			return new ExtReturn(true,"单据反归档成功!");
		} catch(Exception e) {
			loger.error(e.getMessage());
			return new ExtReturn(false,"单据反归档失败,原因:" + e.getMessage());
		}
	}
	@RequestMapping(value = "/getpdfReport.do", method = RequestMethod.GET)  
    public ModelAndView doSalesReportPDF(@RequestParam Long billId){  
		if(billId == null || billId == 0L) {
			return null;
		}
        Bill bill =this.billService.getBill(billId);
        JRDataSource datasource = new JRBillDataSource(bill);  
        Map<String,Object> parameterMap = new HashMap<String,Object>();  
          
 
        parameterMap.put("datasource", datasource);  
        parameterMap.put("title",  WebUtils.BILL_TITLE);

        ModelAndView modelAndView = new ModelAndView("salesStockOutBillReport", parameterMap);  

        return modelAndView;  
    }
	
	@RequestMapping(value = "/getpdfReportBlank.do", method = RequestMethod.GET)  
    public ModelAndView doSalesReportBlankPDF(@RequestParam Long billId){  
		if(billId == null || billId == 0L) {
			return null;
		}
        Bill bill =this.billService.getBill(billId);
        JRDataSource datasource = new JRBillDataSource(bill);  
        Map<String,Object> parameterMap = new HashMap<String,Object>();  
          
 
        parameterMap.put("datasource", datasource);  
        parameterMap.put("title", WebUtils.BILL_TITLE);

        ModelAndView modelAndView = new ModelAndView("salesStockOutBillReportBlank", parameterMap);  

        return modelAndView;  
    }
	
	@RequestMapping(value="/delete.do")
	@ResponseBody
	public Object deleteSaleBill(@RequestParam Long billId) {
		if(billId == null || billId == 0L) {
			return new ExtReturn("参数无效。");
		}
		try {
			
			this.billService.deleteBill(billId);
			return new ExtReturn(true,"单据删除成功!");
		} catch(Exception e) {
			loger.error(e.getMessage());
			return new ExtReturn(false,"单据删除失败,原因:" + e.getMessage());
		}
	}
	@RequestMapping(value = "/getCustomerState.do")
	@ResponseBody
	public Object getCustomerState(@RequestParam Integer custId) {
		try {
			return this.customerService.checkCustomerState(custId);
		} catch (Exception e) {
			this.loger.error(e);
			return new ExtReturn(false,"获取客户状态出错:",e);
		}	
	}
}
